<?php
namespace app\api\controller;

use think\Db;
use think\Controller;
use app\api\model\PayModel;
use app\api\model\IndentModel;

class Pay extends Controller
{

    protected $indent;
    protected $shop;

    public function __construct()
    {
        $this->indent = new IndentModel();
        $this->shop = new PayModel();
    }
    /**
     * 统一下单
     * @param unknown pay_memberid  商户id
     * @param unknown pay_orderid  商户订单号
     * @param unknown pay_amount  订单金额
     * @param unknown pay_date  下单时间
     * @param unknown type_id  支付方式
     * @param unknown pay_md5sign  签名
     * @param unknown pay_notifyurl  回调域名
     */
    public function Unified_order()
    {
        //1,检查参数是否正确
        $parm=$this->checkParm($_POST);
        $data['pay_memberid']=$parm['pay_memberid'];
        $data['pay_orderid']=$parm['pay_orderid'];
        $data['pay_date']=$parm['pay_date'];
        $data['type_id']=$parm['type_id'];
        $data['pay_md5sign']=$parm['pay_md5sign'];
        $data['pay_notifyurl']=$parm['pay_notifyurl'];
        $data['pay_amount']=$parm['pay_amount'];
        //2.检验签名
        $data=$this->checkSign($data);
        //3.生成加密md5订单号
        $shopinfo=$this->shop->where('shopid',$parm['pay_memberid'])->find();
        $ordersnMd5 = md5($this->createOrderNo($shopinfo['id']).$shopinfo['id'].rand(1000,9999));
        $arr             = array();
        $arr['t_number'] = $this->createOrderNo($shopinfo['id']);
        $arr['t_money']  = $parm['pay_memberid'];;
        $arr['z_name']   = $shopinfo['username'];
        $arr['zid']      = $parm['type_id'];
      	$arr['sid']      = 1;
        $arr['z_createtime'] = $parm['pay_date'];
        $arr['ordersn'] = $parm['pay_orderid'];
        $arr['ordersnmd5'] = $ordersnMd5;
        $arr['pay_notifyurl'] = $parm['pay_notifyurl'];
        $res = $this->indent->insert($arr);
        if($res){
            $url = "http://api.mamingwang.cn/index/index/order?ordersn=".$ordersnMd5;
            $ar ['url'] = $url;
            AjaxReturn("1","成功",$ar);
        }else{
            AjaxReturn("-1","下单失败");
        }
    }

    /**
     * 通过订单号查询订单状态
     *
     * @param unknown ordersn
     * @param unknown pay_memberid
     *
     * return  url
     */
    public function pay_trade_query(){
        $pay_memberid = $_POST['pay_memberid'];
        $apikey = $_POST['apikey'];
        $ordersn = $_POST['ordersn'];
        $this->shop_check($pay_memberid,$apikey);
        if(empty($ordersn)){
            AjaxReturn("-10010","参数错误");
        }
        $res = $this->indent->where("ordersnmd5",$ordersn)->find();
        if($res){
            $url = "http://api.mamingwang.cn/index/index/order?ordersn=".$res['ordersnmd5'];
            $arr ['url'] = $url;
            AjaxReturn("1","成功",$arr);
        }else{
            AjaxReturn("-1","没有该订单");
        }
    }
    /**
     * 通过店铺id 得到订单的订单号
     *
     * @param unknown $shop_id
     */
    public function createOrderNo($shop_id)
    {
        $time_str = date('Ymd');
        $order_obj = $this->indent->getFirstData([
            "shopid" => $shop_id
        ], "tid DESC");
        $num = 0;
        if (! empty($order_obj)) {
            $order_no_max = $order_obj["t_number"];
            if (empty($order_no_max)) {
                $num = 1;
            } else {
                if (substr($time_str, 0, 8) == substr($order_no_max, 0, 8)) {
                    $max_no = substr($order_no_max, 8, 7);
                    $num = $max_no * 1 + 1;
                } else {
                    $num = 1;
                }
            }
        } else {
            $num = 1;
        }
        $order_no = $time_str . sprintf("%07d", $num);
        return $order_no;
    }
    //订单完成向商户回调地址推送支付成功信息
    public function sendmsg($tid,$num=1)
    {
        $indent=$this->pay->where('tid',$tid)->find();//查询订单信息
        $parm['pay_orderid']=$indent['t_number'];//商户订单号
        $parm['pay_amount']=$indent['t_money'];
        $parm['type_id']=$indent['t_number'];
        $parm['pay_md5sign']=$this->setSign($parm);
        $xml=$this->ToXml($parm);
        $url=$indent['notifyurl'];
        $result=$this->postXmlCurl($xml,$url);
        if($result!="ok"){
            $time=$num*
            sleep($time);
            $this->sendmsg();
        }
    }
    //检验传值格式
    public function checkParm($data)
    {
        if(!array_key_exists('pay_memberid', $data)){
            AjaxReturn('-10002','缺少商户号');
        }
        if(!array_key_exists('pay_orderid', $data)){
            AjaxReturn('-10003','缺少订单号');
        }
        if(!array_key_exists('pay_amount', $data)){
            AjaxReturn('-10004','缺少订单金额');
        }
        if(!array_key_exists('pay_date', $data)){
            AjaxReturn('-10005','缺少订单时间');
        }
        if(!array_key_exists('type_id', $data)){
            AjaxReturn('-10006','缺少支付方式');
        }
        if(!array_key_exists('pay_md5sign', $data)){
            AjaxReturn('-10007','缺少签名');
        }
        if(!array_key_exists('pay_notifyurl', $data)){
            AjaxReturn('-100010','缺少回调通知地址');
        }
        $shop=$this->shop->where('shopid',$data['pay_memberid'])->find();
        if(!$shop){
            AjaxReturn('-10008','商户号不正确');
        }
        if(!is_numeric($data['pay_amount'])){
            AjaxReturn('-10009','订单金额格式不正确');
        }
        return $data;
    }
    //获取商户密钥key
    public function getKey($pay_memberid)
    {
        $key=$this->shop->where('shopid',$pay_memberid)->find()['appkey'];
        return $key;
    }
    //生成签名
    public function setSign($data)
    {
        if(isset($data['pay_md5sign'])){
            unset($data['pay_md5sign']);
        }
        //获取商户key
        $key=$this->getkey($data['pay_memberid']);
        //签名步骤一：按字典序排序参数
        ksort($data);
        $string = $this->ToUrlParams($data);
        //签名步骤二：在string后加入KEY
        $string = $string . "&key=".$key;
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $string = strtoupper($string);
        return $string;
    }
    //检验签名
    public function checkSign($data)
    {
        $sign=$this->setSign($data);
        if($sign!=$data['pay_md5sign']){
            AjaxReturn("-10001","签名错误");
        }
        return $data;
    }
    /**
    *
    * 拼接签名字符串
    * @param array $urlObj
    *
    * @return 返回已经拼接好的字符串
    */
    private function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v)
        {
            if($k != "sign"){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    /**
     * 输出xml字符
     * @throws WxPayException
     **/
    public function ToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }
    /**
     * 以post方式提交xml到对应的接口url
     * @param string $xml  需要post的xml数据
     * @param string $url  url
     * @param int $second   url执行超时时间，默认60s
     * @throws WxPayException
     */
    private function postXmlCurl($xml, $url, $second = 60)
    {
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch,CURLOPT_URL, $url);
        //设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //运行curl
        $data = curl_exec($ch);
        //返回结果
        curl_close($ch);
        return $data;
    }
}
?>